home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swags_z.zip / SOUND.SWG / 0024_8bit raw sounds.pas < prev    next >
Pascal/Delphi Source File  |  1993-08-27  |  6KB  |  240 lines

  1. {
  2.  
  3.  SoundS.INC  5-27-93  by Steven Tallent
  4.  
  5. This is a Unit to play 8-bit raw Sound Files on any PC, up to 64k
  6. large.  It supports the PC speaker or a DAC (LPT1 or LPT2), although
  7. I do plan to upgrade it to support the SoundBlaster and Adlib Sound
  8. cards.  It is Object-oriented in nature, With one instance of a
  9. speaker defined automatically.  This Unit is public domain, With
  10. code and ideas captured from this echo and Dr. Dobbs Journal.
  11.  
  12. Using the code is simple.  Just setup the the Speaker.Kind,
  13. Speaker.Silent, and Speaker.DisINT to the appropriate values, then
  14. just use the methods included.  The SoundBoard Object is very
  15. flexible For your own code.
  16.  
  17. SoundBoard.Play  - Plays 8-bit music in What^ For Size length, With
  18.                    Speed milliseconds between each Byte, and SampleRate
  19.                    as the sample rate (in Hz).  Speed will need to be
  20.                    changed on different computers (of course).
  21.  
  22. SoundBoard.Sound - Plays a Sound at HZ Hertz, Duration in ms, on
  23.                    VOICE voice.  The code included is useable on
  24.                    the PC speaker (1 voice) or the Tandy speaker
  25.                    (3 voices!).
  26.  
  27. SoundBoard.Reset - Resets the Sound board.
  28.  
  29. SoundBoard.Silent- Convenient Variable that disables all PLAY and Sound
  30.                    if set to True.
  31.  
  32. SoundBoard.DisINT- Disables all interrupts (except during Delays)
  33.                    While using PLAY.
  34.  
  35. This code may be freely distributed, changed, or included in your
  36. own commercial or shareware code, as long as this isn't all your code
  37. does.  This code may be included in commercial or shareware code
  38. libraries only With my permission (I'd like to see someone get some
  39. use out of it).
  40. }
  41.  
  42. Unit Sounds;
  43.  
  44. Interface
  45.  
  46. Type
  47.   BigArray    = Array[0..0] of Byte;
  48.   PBigArray   = ^BigArray;
  49.   KSoundBoard = (PCspeaker, Tandy, DAC1, DAC2, AdLib, SB, SBpro, SB16);
  50.  
  51.   SoundBoard  = Object
  52.     Kind   : KSoundBoard;
  53.     Silent : Boolean;
  54.     DisINT : Boolean;
  55.     Procedure Play(What : PBigArray; Size : Word; Speed : Byte;
  56.                     SampleRate : Word);
  57.     Procedure Sound(Hz, Duration : Word; Voice, Volume : Byte);
  58.     Procedure Reset;
  59.   end;
  60.  
  61. Var
  62.   Speaker : SoundBoard;
  63.  
  64. Procedure Delay(ms : Word);
  65.  
  66. Implementation
  67.  
  68. Procedure SoundBoard.Reset;
  69. begin
  70.   Case Kind of
  71.     PCspeaker, Tandy : Port[97] := Port[97] and $FC;
  72.   end;
  73.   end;
  74.  
  75. Procedure SoundBoard.Sound(Hz, Duration : Word; Voice, Volume : Byte);
  76. Var
  77.   Count   : Word;
  78.   SendByte,
  79.   VoiceID : Byte;
  80. begin
  81.   Case Kind of
  82.     PCspeaker :
  83.       begin
  84.         Count := 1193180 div Hz;
  85.         Port[97] := Port[97] or 3;
  86.         Port[67] := 182;
  87.         Port[66] := Lo(Count);
  88.         Port[66] := Hi(Count);
  89.         Delay(Duration);
  90.         Port[97] := Port[97] and $FC;
  91.       end;
  92.     Tandy :
  93.       begin
  94.         if Voice = 1 then
  95.           VoiceId := 0
  96.         else
  97.         if Voice = 2 then
  98.           VoiceId := 32
  99.         else
  100.           VoiceId := 64;
  101.         Count := 111861 div Hz;
  102.         SendByte := 128 + VoiceId + (Count mod 16);
  103.         Port [$61] := $68;
  104.         Port [$C0] := SendByte;
  105.         Port [$C0] := Count div 16;
  106.         if Voice = 1 then
  107.           VoiceId := 16
  108.         else
  109.         if Voice = 2 then
  110.           VoiceId := 48
  111.         else
  112.           VoiceId := 96;
  113.         SendByte := 128 + VoiceId + (15 - Volume);
  114.         Port [$61] := $68;
  115.         Port [$C0] := SendByte;
  116.         Delay(Duration);
  117.         SendByte := 128 + VoiceId + 15;
  118.         Port [$61] := $68;
  119.         Port [$C0] := SendByte;
  120.     DAC1:;
  121.     DAC2:;
  122.     AdLib:;
  123.     SB:;
  124.     SBPro:;
  125.     SB16:;
  126.   end;
  127.  
  128. Procedure SoundBoard.Play(What : PBigArray; Size : Word;
  129.                           Speed : Byte; SampleRate : Word);
  130. Var
  131.   Loop,
  132.   Count,
  133.   Data  : Word;
  134. begin
  135.   if not Silent then
  136.   begin
  137.     Case Kind of
  138.       PCspeaker, Tandy :
  139.         begin
  140.           Port[97] := Port[97] or 3;
  141.           Count := 1193180 div (SampleRate div 256);
  142.           For Loop := 1 to Size do
  143.           begin
  144.             Data := Count div (What^[Loop] + 1);
  145.             Port[67] := 182;
  146.             Port[66] := Lo(Data);
  147.             Port[66] := Hi(Data);
  148.             Delay(Speed);
  149.             if DisINT then
  150.             Asm
  151.               CLI
  152.             end;
  153.           end;
  154.           Port[97] := Port[97] and $FC;
  155.         end;
  156.  
  157.         DAC1:
  158.           For Loop := 1 to Size do
  159.           begin
  160.             Port [$0378] := What^[Loop];
  161.             Delay (Speed);
  162.             if DisINT then
  163.             Asm
  164.               CLI
  165.             end;
  166.           end;
  167.  
  168.         DAC2:
  169.           For Loop := 1 to Size do
  170.           begin
  171.             Port [$0278] := What^[Loop];
  172.             Delay (Speed);
  173.             if DisINT then
  174.             Asm
  175.               CLI
  176.             end;
  177.           end;
  178.  
  179.         AdLib:;
  180.         SB:;
  181.         SBPro:;
  182.         SB16:;
  183.       end;
  184.       Asm
  185.         STI
  186.       end;
  187.   end;
  188. end;
  189.  
  190. Procedure Delay(ms : Word); Assembler;
  191. Asm
  192.   STI
  193.   MOV AH, $86
  194.   MOV CX, 0
  195.   MOV DX, [ms]
  196.   INT $15
  197. end;
  198.  
  199. end.
  200.  
  201. {-----------------------------------------------------------------
  202. Here's a Program that will accept three values from the command
  203. line, the File, its speed, and the sample rate, and plays it
  204. through the PC speaker.  I've tried in on WAV, VOC, SAM, and even
  205. Amiga sampled Files, With no problems (limited to 64k). I've even
  206. played MOD Files to hear all the sampled instruments!  This Program
  207. does not strip header information, but plays it too, but I can't
  208. hear the difference on WAV and VOC Files.
  209. }
  210. Program TestSnd;
  211. Uses
  212.   Sounds;
  213. Var
  214.   I2   : PBigArray;
  215.   spd  : Integer;
  216.   samp : Word;
  217.   res  : Word;
  218.   siz  : Word;
  219.   s    : String;
  220.   f1   : File of Byte;
  221.   F    : File;
  222. begin
  223.   Speaker.Kind   := PCspeaker;
  224.   Speaker.DisINT := True;
  225.   Speaker.Silent := False;
  226.   s := ParamStr(1);
  227.   Assign(f1,s);  {Get size of File}
  228.   Reset(f1);
  229.   Val (ParamStr(2), Spd, Res);
  230.   Val (ParamStr(3), samp, Res);
  231.   siz := FileSize(f1);
  232.   close(f1);
  233.   Assign(f,s);
  234.   Reset(f);
  235.   getmem (I2,siz);  {Allocate Memory For Sound File}
  236.   BlockRead(f,I2^,siz,res);  {Load Sound into Memory}
  237.   Speaker.Play (i2, siz, spd, samp);
  238.   FreeMem (I2, siz);
  239. end.
  240.